#ifndef GAMEMODEL_H
#define GAMEMODEL_H

#include <bits/stdc++.h>
using namespace std;

/**
 * @enum Type
 * 
 * 控制游戏对战模式：
 * - PERSON: PVP模式(玩家轮流落子)
 * - BOT: PVE战模式(玩家执白，AI执黑)
 */
enum Type
{
    PERSON,
    BOT
};

/**
 * @enum Status
 * 
 * 表示游戏当前状态：
 * - PLAYING: 游戏进行中
 * - WIN: 已有玩家获胜(五子连珠)
 * - DEAD: 和棋状态(棋盘已满)
 */
enum Status
{
    PLAYING, 
    WIN,     
    DEAD    
};

const int kBoardSizeNum = 15; // 棋盘尺寸(15x15)

/**
 * @class GameModel
 * 
 * 1. 更新游戏状态和棋盘数据
 * 2. 处理落子逻辑
 * 3. 实现评分算法
 * 4. 判断游戏胜负
 */
class GameModel
{
public:
    GameModel();

public:
    /* 数据成员 */
    vector<vector<int>> map;  //< 15x15游戏棋盘，0=空位，1=白子，-1=黑子
    vector<vector<int>> scores; //< 评分矩阵，存储每个空位的评估分数
    bool player;  //< 当前玩家标志，true=玩家1(白方)，false=玩家2/AI(黑方)
    Type type; //< 游戏模式，PERSON=双人，BOT=人机
    Status status; //< 游戏状态，PLAYING/WIN/DEAD

    /**
     * @brief 初始化游戏
     * @param type 游戏类型(PVP/PVE)
     * 
     * 1. 清空并初始化15x15游戏棋盘
     * 2. PVE模式,初始化评分矩阵
     * 3. 重置游戏状态为PLAYING
     */
    void start(Type type);

    /**
     * @brief 计算评分
     * 
     * 详细说明：
     * 1. 评估棋盘每个空位的价值
     * 2. 评分规则：
     *    - 连2子: +10
     *    - 活3子: +200(胜负手)
     *    - 冲4子: +60
     *    - 活4子: +110(意义不大)
     *    - 连5子: +10100(直接获胜)
     */
    void calculateScore();

    /**
     * @brief 玩家落子
     * @param row 行坐标(0-14)
     * @param col 列坐标(0-14)
     * 
     * - 更新棋盘
     */
    void playerMove(int row, int col);

    /**
     * @brief 决策落子
     * @param[out] row 返回落子行坐标
     * @param[out] col 返回落子列坐标
     * 
     * 决策流程：
     * 1. 调用calculateScore()计算评分
     * 2. 找出评分最高的位置
     */
    void aiMove(int &row, int &col);

    /**
     * @brief 更新游戏棋盘
     * @param row 行坐标(0-14)
     * @param col 列坐标(0-14)
     * 
     * 功能说明：
     * 1. 根据player设置棋子类型(1或-1)
     * 2. 自动切换待下棋标志
     */
    void updateGameMap(int row, int col);

    /**
     * @brief 判断是否形成五子连珠
     * @param row 最后落子的行坐标
     * @param col 最后落子的列坐标
     * @return true如果形成五子连珠，否则false
     * 
     * 检查四个方向：
     * 1. 水平方向
     * 2. 垂直方向
     * 3. 正对角线(左上到右下)
     * 4. 反对角线(右上到左下)
     */
    bool isWin(int row, int col);

    /**
     * @brief 判断是否和棋
     * @return true如果棋盘已满且未分胜负，否则false
     * 
     * 实现方式：
     * 遍历棋盘所有位置，检查是否全部非空(无0值)
     */
    bool isDeadGame();

    /**
     * @brief 悔棋功能
     * 
     * 功能说明：
     * 1. 从moveHistory栈中弹出最后一步落子
     * 2. 恢复棋盘状态
     * 3. 切换玩家标志
     */
    void undoMove();
};

#endif // GAMEMODEL_H
